import GCJ_CLASS_TYPE = require('./../GCJ_CLASS_TYPE');
import DEFINE = require('./../DEFINE');
import Serializer = require('../../kernel/base/Serializer')
import Parser = require('../../kernel/base/Parser')
import ObjBase = require('../../kernel/obj/ObjBase')


export = SJGNode;
/**
 * 题纲的节点
 * @author 
 *
 */
class SJGNode extends Serializer{
    public static VERSION_1=1;
    public static VERSION_2=2;
    public static VERSION_3=3;
    public static VERSION_4=4;
    public static VERSION_5=5;
    public static VERSION_6=6;
    public static VERSION_7=7;


    //自身加子的整体的类型(0根节点/1数组/2结构体/3叶节点)
    public static SJGNODE_KIND_0=0;
    public static SJGNODE_KIND_1=1;
    public static SJGNODE_KIND_2=2;
    public static SJGNODE_KIND_3=3;

    // 自身（不包含子）的表现形式1(0无/1文字/2图片/3图表/4表格/图形)
    public static SJGNODE_TYPE_0=0;
    public static SJGNODE_TYPE_1=1;
    public static SJGNODE_TYPE_2=2;
    public static SJGNODE_TYPE_3=3;
    public static SJGNODE_TYPE_4=4;
    public static SJGNODE_TYPE_5=5;

    // 属性
    public id: number=DEFINE.ID_NONE; //  节点自身id
    public topic: string=""; // 文本
    public children:Array<SJGNode> = [];// 子对象;
    public kind: number=1; //自身加子的整体的类型(0根节点/1数组/2结构体/3叶节点)
    public type: number=1; // 自身（不包含子）的表现形式1(0无/1文字/2图片/3图表/4表格)

    // 附加属性0
    public value: any=null; // 自身的值，结构根据type而变,(/1-SJGReplaceItemText/2-SJGReplaceItemImage/3-SJGReplaceItemChart)

    // 附加属性1
    public obj_id: number=null; // 版面对象的id   [在分页映射时生成]
    public page_index: number=null; // 节点处于版面的页的下标（>=0）    [在分页映射时生成]

    // 附加属性2
    public child_template: SJGNode=null; // 子的模版，当kind为数组时有效，表示：纪录数组的子和孙子，作为“新增”子时的模版，[在design编辑器保存时生成]
    public child_max: number=1;// 编组在一页中的子的最大个数，[在design编辑器保存时生成]

    // 目前以下节点有效：根节点的直接子节点中的叶节点
    /* 注意：
     * 1、在题纲中，设置保留节点和可选节点，对于保留节点其h必须为1
     * 2、在分页映射中，沿用保留节点和可选节点以及h
     * 3、在编辑器中，设计师勾选的选中项的h需要设置为0，未勾选的h需要设置为1
     * 4、在app中，对于h为1的节点，不需要显示
     *
     */
    public h: number=0; // 1表示隐藏hidden ，否则表示显示，此属性为1时，相应节点的特征值为-1[在题纲编辑器和design编辑器保存时生成]
    public o: number=0; // 1表示可选项optional，否则表示必须项[在题纲编辑器中设置]
    public p: number=0; // 1表示保留的可选节点preserve，否则表示使用中，此属性主要为预防后续增加节点时使用[在题纲编辑器中设置]

    // 临时属性，不需要序列化
    public parent: SJGNode=null;
    public page_content_index: number=null;
    public is_split_node: Boolean=false;//  是否为被分出来的节点
    public visit=0;

    public constructor(g?) {
        super(g);

        this.ct=GCJ_CLASS_TYPE.CLASS_TYPE_SJGNode;
    }
    // 转成json字符串
    public toJson(): string {
        // 去掉父json字符串的头尾
        var superJson=super.toJson();
        superJson=superJson.substr(1,superJson.length-2);

        var ret='{';
        ret+=superJson;

        // id
        ret+=',';
        ret+='"id":';
        ret+=this.id;
        // topic
        ret+=',';
        ret+='"topic":'+'"';
        ret+=this.topic+'"';


        // children
        ret+=',';
        ret+='"children":[';
        for(var i=0;i<this.children.length;i++) {
            if(i>0) {
                ret+=',';
            }
            ret+=this.children[i].toJson();
        }
        ret+=']';

        // kind
        ret+=',';
        ret+='"kind":';
        ret+=this.kind;

        // type
        ret+=',';
        ret+='"type":';
        ret+=this.type;


        // page_index
        if(this.page_index!=null){
            ret+=',';
            ret+='"page_index":';
            ret+=this.page_index;
        }
        // value
        if(this.value) {
            ret+=',';
            ret+='"value":';
            ret+=this.value.toJson();
        }
        // obj_id
        if(this.obj_id) {
            ret+=',';
            ret+='"obj_id":';
            ret+=this.obj_id;
        }

        // child_template
        if(this.child_template){
            ret+=',';
            ret+='"child_template":';
            ret+=this.child_template.toJson();
        }

        // child_max
        ret+=',';
        ret+='"child_max":';
        ret+=this.child_max;

        // h
        ret+=',';
        ret+='"h":';
        ret+=this.h;

        // o
        ret+=',';
        ret+='"o":';
        ret+=this.o;

        // p
        ret+=',';
        ret+='"p":';
        ret+=this.p;



        ret+='}';
        return ret;
    }
    // 转成json字符串
    public toJson2(): string {
        // 去掉父json字符串的头尾
        var superJson=super.toJson();
        superJson=superJson.substr(1,superJson.length-2);

        var ret='{';
        ret+=superJson;

        // id
        ret+=',';
        ret+='"id":';
        ret+=this.id;
        // topic
        ret+=',';
        ret+='"topic":'+'"';
        ret+=this.topic+'"';


        // children
        ret+=',';
        ret+='"children":[';
        for(var i=0;i<this.children.length;i++) {
            if(i>0) {
                ret+=',';
            }
            ret+=this.children[i].toJson2();
        }
        ret+=']';

        // kind
        ret+=',';
        ret+='"kind":';
        ret+=this.kind;

        // type
        ret+=',';
        ret+='"type":';
        ret+=this.type;


        // page_index
        if(this.page_index!=null){
            ret+=',';
            ret+='"page_index":';
            ret+=this.page_index;
        }
        // value
        if(this.value) {
            ret+=',';
            ret+='"value":';
            ret+=this.value.toJson();
        }
        // obj_id
        if(this.obj_id) {
            ret+=',';
            ret+='"obj_id":';
            ret+=this.obj_id;
        }

        // child_template
        if(this.child_template){
            ret+=',';
            ret+='"child_template":';
            ret+=this.child_template.toJson();
        }





        ret+='}';
        return ret;
    }
    // 创建新实例
    public newInstance() {
        return new SJGNode();
    }
    // 从json对象(注意不是json字符串)中解析
    public fromJson(jsonObj,versionId) {
        super.fromJson(jsonObj,versionId);

        this.id=jsonObj.id;
        this.topic=jsonObj.topic;


        if(jsonObj.hasOwnProperty("children")) {
            for(var i=0;i<jsonObj.children.length;i++){
                var child=this.newInstance()

                child.fromJson(jsonObj.children[i],versionId);
                this.children.push(child);

                child.parent=this; // 建立父子关系
            }
        }
        this.kind=jsonObj.kind;
        this.type=jsonObj.type;

        if(jsonObj.hasOwnProperty("page_index")){
            this.page_index=jsonObj.page_index;
            this.page_content_index=0; // page_content_index 初始化成与page_index相同
        }
        if(jsonObj.hasOwnProperty("value")) {
            var one: ObjBase=<ObjBase> Parser.fromUnknownJson(jsonObj.value,versionId,this.getGlobalData());
            if(one) {
                this.value=one;
            }
        }
        if(jsonObj.hasOwnProperty("obj_id")) {
            this.obj_id=jsonObj.obj_id;
        }
        if(jsonObj.hasOwnProperty("child_template")){
            this.child_template=new SJGNode();
            this.child_template.fromJson(jsonObj.child_template, 0);
        }

        //
        if(jsonObj.hasOwnProperty("child_max")) {
            this.child_max=jsonObj.child_max;
        }
        if(jsonObj.hasOwnProperty("h")) {
            this.h=jsonObj.h;
        }
        if(jsonObj.hasOwnProperty("o")) {
            this.o=jsonObj.o;
        }
        if(jsonObj.hasOwnProperty("p")) {
            this.p=jsonObj.p;
        }

    }
    // copy
    public clone():SJGNode{
        var json=this.toJson();
        var ret: SJGNode=new SJGNode();
        ret.fromJson(JSON.parse(json),SJGNode.VERSION_2);
        ret.parent=this.parent; // fromJson不靠背parent，需要显示拷贝
        return ret;
    }
    // 检查数据
    public checkType(): Boolean {
        if(this.type==SJGNode.SJGNODE_TYPE_0) return false;

        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            if(!child.checkType()) return false;
        }
        return true;
    }
    public checkPage(): Boolean {
        if(this.page_index==null) return false;

        for(var i=0;i<this.children.length;i++) {
            var child: SJGNode=this.children[i];
            if(!child.checkPage()) return false;
        }
        return true;
    }
    // 向当前的前面添加兄弟节点
    public addSiblingBefore(node){
        var p=this.parent;
        for(var i = 0; i < p.children.length; i++) {
            var child=p.children[i];
            if(child==this){
                p.children.splice(i,0,node);
                break;
            }
        }
    }
    // 当前节点是否为 组节点  的子
    public is_child_node_of_group_kind() {
        var p=this.parent;
        while(p) {
            if(p.kind==SJGNode.SJGNODE_KIND_1) {
                return true;
            }
            p=p.parent;
        }
        return false;
    }
    // 当前节点是否为 组节点  的子
    public is_child_node_of_group_kind2():Object {
        var p=this.parent;
        while(p) {
            if(p.kind==SJGNode.SJGNODE_KIND_1) {
                return p;
            }
            p=p.parent;
        }
        return null;
    }
    // 更新记录的对象的id
    public updateReplaceItemId(oldId,newId){
        if(this.id!=null) {
            if(this.id==oldId) {
                this.id=newId;
            }
        } else {
            if(this.children && this.children.length){
                for(var i = 0; i < this.children.length; i++) {
                    var child=this.children[i];
                    child.updateReplaceItemId(oldId,newId);
                }
            }
        }
    }
    // 将当前节点的page_index设置到子上
    public set_page_index_to_child() {
        var pi=this.page_index;
        var pci=this.page_content_index;
        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            if(child) {
                child.page_index=pi;
                child.page_content_index=pci;
                child.set_page_index_to_child();
            }
        }

    }
    // 是否为题纲节点对应的文字
    public is_tg_node_obj(id: number): Boolean {
        if(this.obj_id!=null && this.obj_id==id){
            return true;
        }

        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            if(child&&child.is_tg_node_obj(id)) {
                return true;
            }
        }
        return false;
    }
    // 获取叶节点
    public getLeafNodes(): Array<SJGNode> {
        var ret=[];

        if(this.children.length==0) {
            ret.push(this);
        } else {
            for(var i=0;i<this.children.length;i++) {
                var child=this.children[i];
                ret=ret.concat(child.getLeafNodes());
            }
        }


        return ret;
    }
    // 获取编组类型的节点
    public getGroupKindNodes(): Array<SJGNode> {
        var ret=[];

        if(this.kind == SJGNode.SJGNODE_KIND_1) {
            ret.push(this);
        } else {
            for(var i=0;i<this.children.length;i++) {
                var child=this.children[i];
                ret=ret.concat(child.getGroupKindNodes());
            }
        }


        return ret;
    }
    // 将page_index大于指定值的节点加上偏移
    public updatePageIndex(page_index, offset) {
        if(this.page_index>page_index){
            this.page_index+=offset;
        }
        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            child.updatePageIndex(page_index,offset);
        }
    }
    // 设置访问标记
    public setVisit(){
        this.visit=1;
        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            child.setVisit();
        }
    }
    public clearVisit(){
        this.visit=0;
        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            child.clearVisit();
        }
    }
    public isVisit() {
        return this.visit;
    }
    // 根据id取得 node
    public getNodeById(id:number):Object{
        if(this.id==id) return this;
        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            var n=child.getNodeById(id);
            if(n) return n;
        }
        return null;
    }
    // 自身在父中的偏移
    public index():number{
        if(!this.parent) return null;
        return this.parent.getChildIndex(this);
    }
    // 某个子对象在父中的偏移
    public getChildIndex(node:SJGNode):number{
        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            if(child==node) return i;
        }
        return null;
    }
    // 取得数组类型节点的某一级的所有孙子
    public getGroupGrandSonOfLevel(level:number):SJGNode[]{
        //自身加子的整体的类型(0根节点/1数组/2结构体/3叶节点)
        var ret=[];
        if(this.kind==SJGNode.SJGNODE_KIND_1){
            for(var i=0;i<this.children.length;i++) {
                var child=this.children[i];
                var grandSon = child.children[level];
                ret.push(grandSon);
            }
        }
        return ret;
    }

    // 更新数组节点的child_template
    public updateChildTemplate() {
        var ret=this.getGroupKindNodes();
        for(var i=0;i<ret.length; i++) {
            var one=ret[i];
            one.child_template=one.children[0];
        }
    }
    // 根据obj_id取得 node
    public getNodeByObjId(obj_id: number): Object {
        if(this.obj_id==obj_id) return this;
        for(var i=0;i<this.children.length;i++) {
            var child=this.children[i];
            var n=child.getNodeByObjId(obj_id);
            if(n) return n;
        }
        return null;
    }
//SJG_MARK_APPEND--------------------


}//SJG_MARK_END-------------------------